package com.example.ccj.b.c.custom.tree;


import android.annotation.SuppressLint;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.example.ccj.R;
import com.example.ccj.u.ImageUtils;
import com.example.ccj.u.SizeUtils;
import com.example.ccj.u.StringUtils;
import com.example.ccj.u.ThreadUtils;
import com.example.ccj.u.ThreadUtilsListener;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 *
 * @author 驰珺
 * whechat   : chijun9
 * create at : 2024/11/22 0:37
 */
public class TreeAdapter extends RecyclerView.Adapter<TreeAdapter.ViewHolder>{
    private final List<TreeMode> treeModeList;
    public Map<String,TreeMode> selectedTree;
    private final Map<Integer,TreeMode> muLuMap;
    private final ISelectTreeListener selectTreeListener;

    static RequestOptions requestOptions = RequestOptions
            .bitmapTransform(new RoundedCorners(SizeUtils.dp2px(10)));

    /**
     *
     * @param treeModeList 数据
     * @param selectedTree 默认选中的数据
     * @param selectTreeListener 回调
     */
    public TreeAdapter(List<TreeMode> treeModeList,Map<String,TreeMode> selectedTree,ISelectTreeListener selectTreeListener){
        this.treeModeList = treeModeList;
        this.selectedTree = selectedTree;
        this.selectTreeListener = selectTreeListener;

        if (this.selectedTree == null) this.selectedTree = new HashMap<>();
        muLuMap = new HashMap<>();
        for (TreeMode treeMode : treeModeList) {
            if (selectedTree != null && selectedTree.containsKey(treeMode.dataId)) treeMode.isChecked = true;
            if (treeMode.type == TreeMode.DATA_TYPE_MU_LU) muLuMap.put(treeMode.id,treeMode);
        }
    }

    private int iconMuLu = 0;                               //目录默认图片资源ID
    private int iconData = 0;                               //数据默认图片资源ID
    private int suoJinLevel = 3;                            //子节点相对缩进级别,每个级别增加10dp


    //设置目录默认图片资源id
    public void setMuLuDefaultImageResource(int imageResourceId){
        this.iconMuLu = imageResourceId;
    }
    //设置数据默认图片资源id
    public void setDataDefaultImageResource(int imageResourceId){
        this.iconData = imageResourceId;
    }
    //设置缩进级别
    public void setSuoJinJiBie(int suoJinLevel){
        this.suoJinLevel = suoJinLevel;
    }

    @NonNull
    @Override
    public TreeAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new TreeAdapter.ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_tree, parent, false));
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void onBindViewHolder(@NonNull TreeAdapter.ViewHolder holder, int position) {
        TreeMode treeMode = treeModeList.get(position);
        holder.name.setText(treeMode.name + "--" + position);
        //是否显示
        if (treeMode.isVisibility) {
            holder.lL.setVisibility(View.VISIBLE);
            //左偏移距离
            holder.lL.setPadding(suoJinLevel*10*treeMode.level,0,0,0);
            //判断子节点显示时，上级节点是否已展开
            jjiu(treeMode,holder);

            //箭头是否显示，只有文件夹显示折叠箭头
            if (treeMode.type == TreeMode.DATA_TYPE_MU_LU) {
                holder.jianTou.setVisibility(View.VISIBLE);
                //文件夹添加展开关闭事件
                holder.jianTou.setOnClickListener(v -> zhanKai(treeMode));
                //是否是展开状态，展开的非展开状态下显示的图片
                if (treeMode.isExpand) holder.jianTou.setImageResource(R.drawable.tree_bottom);
                //折叠显示图片
                else holder.jianTou.setImageResource(R.drawable.tree_right);
            } else holder.jianTou.setVisibility(View.INVISIBLE);

            //设置图标
            if (treeMode.type == TreeMode.DATA_TYPE_MU_LU) {
                if (!StringUtils.isEmpty(treeMode.icon)) {
                    holder.icon.setVisibility(View.VISIBLE);
                    ImageUtils.loadImage(holder.icon.getContext(),treeMode.icon,holder.icon,requestOptions);
                } else if (iconMuLu > 0) {
                    holder.icon.setVisibility(View.VISIBLE);
                    ImageUtils.loadImage(holder.icon.getContext(),iconMuLu,holder.icon,requestOptions);
                } else holder.icon.setVisibility(View.GONE);
            } else if (treeMode.type == TreeMode.DATA_TYPE_DATA) {
                if (!StringUtils.isEmpty(treeMode.icon)) {
                    holder.icon.setVisibility(View.VISIBLE);
                    ImageUtils.loadImage(holder.icon.getContext(),treeMode.icon,holder.icon,requestOptions);
                } else if (iconData > 0) {
                    holder.icon.setVisibility(View.VISIBLE);
                    ImageUtils.loadImage(holder.icon.getContext(),iconData,holder.icon,requestOptions);
                } else holder.icon.setVisibility(View.GONE);
            }
        } else {
            holder.lL.setVisibility(View.GONE);
        }

        //是否选中处理
        //传入的数据中是否存在选中的
        holder.select.setOnCheckedChangeListener(null);
        holder.select.setChecked(treeMode.isChecked);
        holder.select.setOnCheckedChangeListener((buttonView, isChecked) -> {
            //选中处理
            if (isChecked) xuanZhong(treeMode,holder);
            else cancelSelect(treeMode,holder);
        });
    }

    //判断子节点显示时，上级节点是否已展开
    private void jjiu(TreeMode treeMode,TreeAdapter.ViewHolder holder){
        TreeMode treeMode1 = muLuMap.get(treeMode.pId);
        //下级节点显示了上级节点未显示时
        if (treeMode1 != null ) {
            if (!treeMode1.isVisibility || !treeMode1.isExpand) {
                treeMode1.isVisibility = true;
                if (treeMode1.type == TreeMode.DATA_TYPE_MU_LU) treeMode1.isExpand = true;
                holder.itemView.post(() -> notifyItemChanged(treeMode1.id));
                List<TreeMode> treeModeList1 = treeMode1.treeModeList;
                if (treeModeList1 != null) {
                    for (TreeMode mode : treeModeList1) {
                        mode.isVisibility = true;
                        if (treeMode1.type == TreeMode.DATA_TYPE_MU_LU) mode.isExpand = true;
                        holder.itemView.post(() -> notifyItemChanged(treeMode1.id));
                        jjiu(mode,holder);
                    }
                }
            }
        }
    }

    /**
     * 取消选中处理
     * @param treeMode 1
     */
    private void cancelSelect(TreeMode treeMode,TreeAdapter.ViewHolder holder){
        //取消选中目录节点
        if (treeMode.type == TreeMode.DATA_TYPE_MU_LU) {
            //将该目录下的所有节点全部取消选中
            ThreadUtils.executeByIo(new ThreadUtilsListener<Integer>() {
                @Override
                public Integer doInBackground()  {
                    cancelMuLuXiaJieDian(treeMode,holder);
                    cancelMuLuShangJieDian(treeMode,holder);
                    return null;
                }
            });
        } else {
            treeMode.isChecked = false;
            holder.itemView.post(() -> notifyItemChanged(treeMode.id));
            cancelMuLuShangJieDian(treeMode,holder);
        }
    }

    /**
     * 取消选中该节点以上的主节点
     * @param treeMode 节点
     * @param holder 1
     */
    private void cancelMuLuShangJieDian(TreeMode treeMode, TreeAdapter.ViewHolder holder){
        //取消选中数据回调
        treeMode.isChecked = false;
        if (selectTreeListener != null) selectTreeListener.delete(treeMode);
        holder.itemView.post(() -> notifyItemChanged(treeMode.id));
        if (muLuMap.containsKey(treeMode.pId)) {
            TreeMode treeMode1 = muLuMap.get(treeMode.pId);
            if (treeMode1 != null) {
                if (treeMode1.isChecked) {
                    cancelMuLuShangJieDian(treeMode1,holder);
                }
            }
        }
    }

    //取消选中目录下所有节点，只取消选中不折叠 递归取消
    private void cancelMuLuXiaJieDian(TreeMode treeMode, TreeAdapter.ViewHolder holder){
        treeMode.isChecked = false;//取消选中

        //取消选中数据回调
        if (selectTreeListener != null) selectTreeListener.delete(treeMode);

        holder.itemView.post(() -> notifyItemChanged(treeMode.id));
        //如果需要折叠调用,会反向执行，当前展开的折叠，折叠的展开
//        zhanKai(treeMode);
        List<TreeMode> treeModeList1 = treeMode.treeModeList;
        if (treeModeList1 != null) {
            for (TreeMode mode : treeModeList1) {
                cancelMuLuXiaJieDian(mode,holder);
            }
        }
    }

    /**
     * 选中处理
     * @param treeMode 选中的节点
     * @param holder 用来主线程更新UI
     */
    private void xuanZhong(TreeMode treeMode,TreeAdapter.ViewHolder holder){
        ThreadUtils.executeByIo(new ThreadUtilsListener<Integer>() {
            @Override
            public Integer doInBackground() throws Throwable {
                diGuiWenJianJiaSuoYouWenJian(treeMode,holder);
                return null;
            }
        });
    }

    private void diGuiWenJianJiaSuoYouWenJian(TreeMode treeMode,TreeAdapter.ViewHolder holder){
        treeMode.isChecked = true;
        treeMode.isExpand = true;
        treeMode.isVisibility = true;

        //选中数据回调 这里返回的是包含目录节点以及数据节点的数据，如果需要该目录全选时只返回目录模型请自行筛选
        if (selectTreeListener != null) selectTreeListener.select(treeMode);

        holder.itemView.post(() -> notifyItemChanged(treeMode.id));
        if (treeMode.type == TreeMode.DATA_TYPE_MU_LU) {
            List<TreeMode> treeModeList1 = treeMode.treeModeList;
            if (treeModeList1 != null) {
                for (TreeMode mode : treeModeList1) {
                    diGuiWenJianJiaSuoYouWenJian(mode,holder);
                }
            }
        }
    }

    //展开关闭
    private void zhanKai(TreeMode treeMode){
        treeMode.isExpand = !treeMode.isExpand;
        notifyItemChanged(treeMode.id);
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                closeOrOpen(treeMode,e);
            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {}
                    @Override
                    public void onNext(Integer integer) {
                        notifyItemChanged(integer);
                    }
                    @Override
                    public void onError(Throwable e) {}
                    @Override
                    public void onComplete() {}
                });
    }

    private void closeOrOpen(TreeMode treeMode , ObservableEmitter<Integer> e){
        List<TreeMode> treeModeList = treeMode.treeModeList;
        if (treeModeList != null) {
            for (TreeMode mode : treeModeList) {
                mode.isVisibility = treeMode.isExpand;
                mode.isExpand = false;
                e.onNext(mode.id);
                if (mode.type == TreeMode.DATA_TYPE_MU_LU) closeOrOpen(mode,e);
            }
        }
    }


    @Override
    public int getItemCount() {
        return treeModeList == null ? 0 : treeModeList.size();
    }


    @Override
    public int getItemViewType(int position) {
        return position;
    }

    //
    public static class ViewHolder extends RecyclerView.ViewHolder{
        private final TextView name;
        private final ImageView icon,jianTou;
        private final LinearLayout lL;
        private final CheckBox select;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            lL = itemView.findViewById(R.id.adapter_tree_ll);
            icon = itemView.findViewById(R.id.adapter_tree_icon);
            jianTou = itemView.findViewById(R.id.adapter_tree_jian_tou);
            name = itemView.findViewById(R.id.adapter_tree_text);
            select = itemView.findViewById(R.id.adapter_tree_select);
        }
    }



}
